package com.goldsprite.gsgengine.core.managers;

import com.goldsprite.gsgengine.core.gameobjects.GameObject;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 游戏物体管理器作为全局顶级管理器管理所有游戏物体
 */

public class GameObjectManager extends Manager {
	private static GameObjectManager instance;
	private static int uuidSeed = 0; // 静态计数器用于生成唯一 ID
	private final Map<String, GameObject> gameObjects = new ConcurrentHashMap<>(); // ID 和 GameObject 的映射

	public GameObjectManager() {
		if (instance != null) {
			throw new RuntimeException("非法创建实例，仅允许1个GameObjectManager实例存在");
		}
		instance = this;
	}

	public static GameObjectManager getInstance() {
		if (instance == null) {
			throw new IllegalStateException("GameObjectManager尚未初始化");
		}
		return instance;
	}

	public synchronized String getUuidSeed() {
		return String.valueOf(uuidSeed++);
	}

	public GameObject instantiateEntity(GameObject entity) {
		String uuid = entity.getUuid();
		if (gameObjects.containsKey(uuid)) {
			throw new IllegalArgumentException("重复添加GameObject: " + uuid);
		}
		gameObjects.put(uuid, entity);
		return entity;
	}

	public void destroyGameObject(GameObject entity) {
		if (entity == null || !gameObjects.containsKey(entity.getUuid())) {
			throw new IllegalArgumentException("未找到目标GameObject: " + (entity != null ? entity.getUuid() : "null"));
		}
		destroyGameObject(entity.getUuid());
	}

	public void destroyGameObject(String id) {
		GameObject entity = gameObjects.remove(id);
		if (entity == null) {
			throw new IllegalArgumentException("未找到目标GameObject: " + id);
		}
		entity.destroy();
	}

	public GameObject getGameObject(String id) {
		return gameObjects.get(id); // 查找方法
	}

	public void start() {
		gameObjects.values().stream()
			.filter(GameObject::isEnable)
			.forEach(GameObject::start);
	}

	public void fixedUpdate(float fixedDelta) {
		gameObjects.values().forEach(ent -> ent.fixedUpdate(fixedDelta));
	}

	public void update(float delta) {
		gameObjects.values().forEach(ent -> ent.update(delta));
	}

	public void destroy() {
		gameObjects.values().forEach(GameObject::destroy);
		gameObjects.clear();
	}
}
